home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 121_01 / fseek.c < prev    next >
Text File  |  1985-08-19  |  4KB  |  130 lines

  1. /*
  2. HEADER: CUG 121.??;
  3.  
  4.     TITLE:    fseek - routines for more.c;
  5.     VERSION:    1.0;
  6.     DATE:    08/01/85;
  7.     DESCRIPTION: "This module provides two functions: (1) fseek - seek to
  8.         a character position in file, and (2) ftell - says where
  9.         in file you are.  These provide Unix-like facilities for
  10.         character seek & positional query to BDS C programs.";
  11.     KEYWORDS:    buffered, seek;
  12.     SYSTEM:    CP/M;
  13.     FILENAME:    FSEEK.C;
  14.     AUTHORS:    Mike W. Meyer;
  15.     COMPILERS:    BDS-C 1.50;
  16. */
  17. /*
  18.  * fseek.c - subroutines to provide Unix-like facilities for BDS C
  19.  *
  20.  *    Description
  21.  *      This module provides two functions:
  22.  *        fseek - seek to character position in file
  23.  *        ftell - says where in file you are
  24.  *
  25.  *
  26.  * fseek - a character seek for the BDS C buffered I/O routines
  27.  *
  28.  *      This routine is used by more.c.  It provides a Unix-like character
  29.  *    seek for BDS C.  Arguments -
  30.  *        f - the I/O Buffer pointer
  31.  *        tosec - an int saying where we want to be
  32.  *        code - Tells how to interpret tosec:
  33.  *            code = 0) absolute, characters
  34.  *            code = 1) relative, characters
  35.  *            code = 2) * from end, characters
  36.  *            code = 3) absolute, sectors
  37.  *            code = 4) relative, sectors
  38.  *            code = 5) * from end, sectors
  39.  *    * - not implemented, but there to model the
  40.  *        Unix V6 seek call.
  41.  *    mwm 2/81
  42.  */
  43.  
  44. #include <bdscio.h>
  45.  
  46. fseek(f, tosec, code)
  47. struct _buf *f;
  48. {
  49. int bchar, cchar, tochar;
  50. unsigned bsec, csec, wsec;
  51. /*
  52.  * The variable names -
  53.  *    bX is the buffer length, in X's.
  54.  *    Xchar is a character offset in a sector.
  55.  *    Xsec is a sector offset in the file.
  56.  *    toX is where we want to go to.
  57.  *    wsec is the next sector to be read.
  58.  *    cX is where we are.
  59.  */
  60.     /* extract some info about the buffer */
  61.     bsec = (bchar = f -> _nextp - f -> _buff + f -> _nleft) / SECSIZ;
  62.  
  63.     /* now, find out where we are */
  64.     if ((wsec = tell(f -> _fd)) == ERROR)
  65.         return(ERROR);
  66.     cchar = bchar - f -> _nleft;
  67.     csec = wsec - bsec + cchar / SECSIZ;
  68.     cchar %= SECSIZ;
  69.  
  70.     /* Next, where do we want to be */
  71.     if (code > 2) {    /* by sectors, the easy part */
  72.         tochar = cchar;
  73.         if (code == 4)
  74.             /* don't seek past 0 */
  75.             if (tosec < 0 && abs(tosec) > csec)
  76.                 tochar = tosec = 0;
  77.             else tosec += csec;
  78.         else if (code != 3)
  79.             return(ERROR);
  80.     }
  81.     else {        /* by characters.  Hard */
  82.         tochar = tosec % SECSIZ;
  83.         tosec /= SECSIZ;
  84.         if (code == 1) {
  85.             tochar += cchar;
  86.             tosec += tochar / SECSIZ;
  87.             tochar %= SECSIZ;
  88.             if (tosec < 0 && abs(tosec) > csec)
  89.                 tochar = tosec = 0;
  90.             else tosec += csec;
  91.         }
  92.         else if (code != 0)
  93.             return(ERROR);
  94.     }
  95.  
  96.     /* Now go there! */
  97.     if (tosec < wsec && tosec > wsec - bsec) {
  98.         /* in the buffer, just rearrange things */
  99.         tochar += (bsec - (wsec - tosec)) * SECSIZ;
  100.             f -> _nleft = bchar - tochar;
  101.         f -> _nextp = f -> _buff + tochar;
  102.         return(OK);
  103.     }
  104.         /* Not in the buffer, so set the I/O pointer,
  105.            and then rearrange the buffer */
  106.     if (seek(f -> _fd, tosec, 0) == ERROR)
  107.         return(ERROR);
  108.     f -> _nleft = 0;
  109.     getc(f);    /* force the buffer to be filled */
  110.     f -> _nextp = f -> _buff + tochar;
  111.     f -> _nleft++;
  112.     f -> _nleft -= tochar;
  113.     return(OK);
  114. }
  115. /*
  116.  * ftell - a tell for BDS C buffered I/O
  117.  *
  118.  *    Argument -
  119.  *        file - the I/O Buffer pointer
  120.  */
  121. unsigned ftell(file)
  122. struct _buf *file;
  123. {
  124. unsigned wsec, bsec, csec;
  125.  
  126.     if ((wsec = tell(file -> _fd)) == ERROR)
  127.         return(ERROR);
  128.     return(SECSIZ * wsec - file -> _nleft);
  129. }
  130.